#include "_u8_Lib.h"
#include "_0_96OLED_Lib.h"
#include "FontLib.h"
#include "sys.h"


void Screen_Init(SCREEN* Screen,char SCK_GPIOx,u16 SCK_pin,char SDA_GPIOx,u16 SDA_pin)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    
    Screen->SDA_pin = 1<<SDA_pin;
    Screen->SCK_pin = 1<<SCK_pin;
    Screen->SDA_GPIOx = (GPIO_TypeDef *)(APB2PERIPH_BASE+0x0800+(SDA_GPIOx-'A')*0x400);
    Screen->SCK_GPIOx = (GPIO_TypeDef *)(APB2PERIPH_BASE+0x0800+(SCK_GPIOx-'A')*0x400);
    
    RCC_APB2PeriphClockCmd(4<<(SDA_GPIOx-'A'),ENABLE);
    RCC_APB2PeriphClockCmd(4<<(SCK_GPIOx-'A'),ENABLE);
    
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    
    GPIO_InitStructure.GPIO_Pin = Screen->SDA_pin;
    GPIO_Init(Screen->SDA_GPIOx, &GPIO_InitStructure);
    GPIO_SetBits(Screen->SDA_GPIOx, Screen->SDA_pin);
    
    GPIO_InitStructure.GPIO_Pin = Screen->SCK_pin;
    GPIO_Init(Screen->SCK_GPIOx, &GPIO_InitStructure);
    GPIO_SetBits(Screen->SCK_GPIOx, Screen->SCK_pin);
	
//	Screen->SDA_pin = 1<<SDA_pin;
//    Screen->SCK_pin = 1<<SCK_pin;
//    Screen->SDA_GPIOx = GPIO_GetX(SDA_GPIOx);
//    Screen->SCK_GPIOx = GPIO_GetX(SCK_GPIOx);
//    
//    GPIO_PP_Config(SCK_GPIOx, SCK_pin, 1);
//    GPIO_PP_Config(SDA_GPIOx, SDA_pin, 1);
    
    Screen_WR_Byte(Screen, 0xAE, SCREEN_CMD);//--turn off oled panel
	Screen_WR_Byte(Screen, 0x00, SCREEN_CMD);//---set low column address
	Screen_WR_Byte(Screen, 0x10, SCREEN_CMD);//---set high column address
	Screen_WR_Byte(Screen, 0x40, SCREEN_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
	Screen_WR_Byte(Screen, 0x81, SCREEN_CMD);//--set contrast control register
	Screen_WR_Byte(Screen, 0xCF, SCREEN_CMD);// Set SEG Output Current Brightness
	Screen_WR_Byte(Screen, 0xA1, SCREEN_CMD);//--Set SEG/Column Mapping     0xa0×óÓÒ·´ÖÃ 0xa1Õý³£
	Screen_WR_Byte(Screen, 0xC8, SCREEN_CMD);//Set COM/Row Scan Direction   0xc0ÉÏÏÂ·´ÖÃ 0xc8Õý³£
	Screen_WR_Byte(Screen, 0xA6, SCREEN_CMD);//--set normal display
	Screen_WR_Byte(Screen, 0xA8, SCREEN_CMD);//--set multiplex ratio(1 to 64)
	Screen_WR_Byte(Screen, 0x3f, SCREEN_CMD);//--1/64 duty
	Screen_WR_Byte(Screen, 0xD3, SCREEN_CMD);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	Screen_WR_Byte(Screen, 0x00, SCREEN_CMD);//-not offset
	Screen_WR_Byte(Screen, 0xd5, SCREEN_CMD);//--set display clock divide ratio/oscillator frequency
	Screen_WR_Byte(Screen, 0x80, SCREEN_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
	Screen_WR_Byte(Screen, 0xD9, SCREEN_CMD);//--set pre-charge period
	Screen_WR_Byte(Screen, 0xF1, SCREEN_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	Screen_WR_Byte(Screen, 0xDA, SCREEN_CMD);//--set com pins hardware configuration
	Screen_WR_Byte(Screen, 0x12, SCREEN_CMD);
	Screen_WR_Byte(Screen, 0xDB, SCREEN_CMD);//--set vcomh
	Screen_WR_Byte(Screen, 0x40, SCREEN_CMD);//Set VCOM Deselect Level
	Screen_WR_Byte(Screen, 0x20, SCREEN_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
	Screen_WR_Byte(Screen, 0x02, SCREEN_CMD);//
	Screen_WR_Byte(Screen, 0x8D, SCREEN_CMD);//--set Charge Pump enable/disable
	Screen_WR_Byte(Screen, 0x14, SCREEN_CMD);//--set(0x10) disable
	Screen_WR_Byte(Screen, 0xA4, SCREEN_CMD);// Disable Entire Display On (0xa4/0xa5)
	Screen_WR_Byte(Screen, 0xA6, SCREEN_CMD);// Disable Inverse Display On (0xa6/a7) 
	Screen_WR_Byte(Screen, 0xAF, SCREEN_CMD);

	Screen_Clear(Screen);
    
}




void Screen_I2C_Start(SCREEN* Screen)
{
    SCREEN_SDIN_Set(Screen);
	SCREEN_SCLK_Set(Screen);
	SCREEN_SDIN_Clr(Screen);
	SCREEN_SCLK_Clr(Screen);

}


void Screen_I2C_Stop(SCREEN* Screen)
{
	SCREEN_SCLK_Set(Screen);
	SCREEN_SDIN_Clr(Screen);
	SCREEN_SDIN_Set(Screen);

}


void Screen_I2C_WaitAck(SCREEN* Screen)
{
    SCREEN_SCLK_Set(Screen);
	SCREEN_SCLK_Clr(Screen);

}


void Screen_Send_Byte(SCREEN* Screen, u8 dat)
{
	u8 i;
	for(i=0;i<8;i++)
	{
		SCREEN_SCLK_Clr(Screen);//将时钟信号设置为低电平
		if(dat&0x80)//将dat的8位从最高位依次写入
		{
			SCREEN_SDIN_Set(Screen);
    	}
		else
		{
			SCREEN_SDIN_Clr(Screen);
        }
		SCREEN_SCLK_Set(Screen);//将时钟信号设置为高电平
		SCREEN_SCLK_Clr(Screen);//将时钟信号设置为低电平
		dat<<=1;
  	}    
}


void Screen_WR_Byte(SCREEN* Screen, u8 dat,u8 mode)
{
    Screen_I2C_Start(Screen);
	Screen_Send_Byte(Screen, 0x78);
	Screen_I2C_WaitAck(Screen);
	if(mode){Screen_Send_Byte(Screen,0x40);}
    else{Screen_Send_Byte(Screen,0x00);}
	Screen_I2C_WaitAck(Screen);
	Screen_Send_Byte(Screen, dat);
	Screen_I2C_WaitAck(Screen);
	Screen_I2C_Stop(Screen);
}


void Screen_WR_BP(SCREEN* Screen, u8 x,u8 y)
{
	Screen_WR_Byte(Screen,0xb0+y,SCREEN_CMD);//设置行起始地址
	Screen_WR_Byte(Screen,((x&0xf0)>>4)|0x10,SCREEN_CMD);
	Screen_WR_Byte(Screen,(x&0x0f),SCREEN_CMD);

}


void Screen_DisPlay_On(SCREEN* Screen)
{
    Screen_WR_Byte(Screen, 0x8D, SCREEN_CMD);//电荷泵使能
	Screen_WR_Byte(Screen, 0x14, SCREEN_CMD);//开启电荷泵
	Screen_WR_Byte(Screen, 0xAF, SCREEN_CMD);//点亮屏幕
}


void Screen_DisPlay_Off(SCREEN* Screen)
{
    Screen_WR_Byte(Screen, 0x8D, SCREEN_CMD);//电荷泵使能
	Screen_WR_Byte(Screen, 0x10, SCREEN_CMD);//开启电荷泵
	Screen_WR_Byte(Screen, 0xAF, SCREEN_CMD);//点亮屏幕
}
void Screen_Refresh(SCREEN* Screen)
{
    u8 i,n;
	for(i=0;i<8;i++)
	{
        Screen_WR_Byte(Screen, 0xb0+i,SCREEN_CMD); //设置行起始地址
        Screen_WR_Byte(Screen, 0x00,SCREEN_CMD);   //设置低列起始地址
        Screen_WR_Byte(Screen, 0x10,SCREEN_CMD);   //设置高列起始地址
        for(n=0;n<128;n++)
		    Screen_WR_Byte(Screen, Screen->Screen_GRAM[n][i],SCREEN_DATA);
    }
}


void Screen_DrawPoint(SCREEN* Screen, u8 x,u8 y)
{
    u8 i,m,n;
	i=y/8;
	m=y%8;
	n=1<<m;
	Screen->Screen_GRAM[x][i]|=n;
}


void Screen_ClearPoint(SCREEN* Screen, u8 x,u8 y)
{
    u8 i,m,n;
	i=y/8;
	m=y%8;
	n=1<<m;
	Screen->Screen_GRAM[x][i]=~(Screen->Screen_GRAM[x][i]);
	(Screen->Screen_GRAM[x][i])|=n;
	Screen->Screen_GRAM[x][i]=~(Screen->Screen_GRAM[x][i]);
}


void Screen_ColorTurn(SCREEN* Screen, u8 i)
{
    if(i==0)
    {
        Screen_WR_Byte(Screen, 0xA6,SCREEN_CMD);//正常显示
    }
	if(i==1)
    {
        Screen_WR_Byte(Screen, 0xA7,SCREEN_CMD);//反色显示
    }
}


void Screen_DisplayTurn(SCREEN* Screen, u8 i)
{
    if(i==0)
    {
        Screen_WR_Byte(Screen, 0xC8,SCREEN_CMD);//正常显示
        Screen_WR_Byte(Screen, 0xA1,SCREEN_CMD);
    }
	if(i==1)
    {
        Screen_WR_Byte(Screen, 0xC0,SCREEN_CMD);//反转显示
        Screen_WR_Byte(Screen, 0xA0,SCREEN_CMD);
    }
}


void Screen_Clear(SCREEN* Screen)
{
    u8 i,n;
	for(i=0;i<8;i++)
	{
	    for(n=0;n<128;n++)
		{
			Screen->Screen_GRAM[n][i]=0;//清除所有数据
		}
  	}
	Screen_Refresh(Screen);//更新显示
}

void Screen_DrawLine(SCREEN* Screen, u8 x1,u8 y1,u8 x2,u8 y2)
{
    u8 i,k,k1,k2;
	if((x2>128)||(y2>64)||(x1>x2)||(y1>y2))return;
	if(x1==x2)    //画竖线
	{
        for(i=0;i<(y2-y1);i++)
        {
            Screen_DrawPoint(Screen, x1,y1+i);
        }
    }
	else if(y1==y2)   //画横线
	{
        for(i=0;i<(x2-x1);i++)
        {
            Screen_DrawPoint(Screen, x1+i,y1);
        }
    }
	else      //画斜线
	{
		k1=y2-y1;
		k2=x2-x1;
		k=k1*10/k2;
		for(i=0;i<(x2-x1);i++)
        {
            Screen_DrawPoint(Screen, x1+i,y1+i*k/10);
        }
	}
}


void Screen_DrawCircle(SCREEN* Screen, u8 x,u8 y,u8 r)
{
    int a, b,num;
    a = 0;
    b = r;
    while(2 * b * b >= r * r)      
    {
        Screen_DrawPoint(Screen, x + a, y - b);
        Screen_DrawPoint(Screen, x - a, y - b);
        Screen_DrawPoint(Screen, x - a, y + b);
        Screen_DrawPoint(Screen, x + a, y + b);
 
        Screen_DrawPoint(Screen, x + b, y + a);
        Screen_DrawPoint(Screen, x + b, y - a);
        Screen_DrawPoint(Screen, x - b, y - a);
        Screen_DrawPoint(Screen, x - b, y + a);
        
        a++;
        num = (a * a + b * b) - r*r;//计算画的点离圆心的距离
        if(num > 0)
        {
            b--;
            a--;
        }
    }
}


void Screen_ShowChar(SCREEN* Screen, u8 x,u8 y,u8 chr,u8 size1)
{
    u8 i,m,temp,size2,chr1;
	u8 y0=y;
	size2=(size1/8+((size1%8)?1:0))*(size1/2);  //得到字体一个字符对应点阵集所占的字节数
	chr1=chr-' ';  //计算偏移后的值
	for(i=0;i<size2;i++)
	{
		if(size1==12)
        {temp=ascii_fontlib_1206[chr1][i];} //调用1206字体
		else if(size1==16)
        {temp=ascii_fontlib_1608[chr1][i];} //调用1608字体
		else if(size1==24)
        {temp=ascii_fontlib_2412[chr1][i];} //调用2412字体
		else return;
		for(m=0;m<8;m++)           //写入数据
		{
			if(temp&0x80)Screen_DrawPoint(Screen, x,y);
			else Screen_ClearPoint(Screen, x, y);
			temp<<=1;
			y++;
			if((y-y0)==size1)
			{
				y=y0;
				x++;
				break;
			}
		}
	}
}
void Screen_ShowBackChar(SCREEN* Screen, u8 x,u8 y,u8 chr,u8 size1)
{
    u8 i,m,temp,size2,chr1;
	u8 y0=y;
	size2=(size1/8+((size1%8)?1:0))*(size1/2);  //得到字体一个字符对应点阵集所占的字节数
	chr1=chr-' ';  //计算偏移后的值
	for(i=0;i<size2;i++)
	{
		if(size1==12)
        {temp=ascii_fontlib_1206[chr1][i];} //调用1206字体
		else if(size1==16)
        {temp=ascii_fontlib_1608[chr1][i];} //调用1608字体
		else if(size1==24)
        {temp=ascii_fontlib_2412[chr1][i];} //调用2412字体
		else return;
		for(m=0;m<8;m++)           //写入数据
		{
			if(temp&0x80)Screen_ClearPoint(Screen, x,y);
			else Screen_DrawPoint(Screen, x, y);
			temp<<=1;
			y++;
			if((y-y0)==size1)
			{
				y=y0;
				x++;
				break;
			}
		}
	}    
}


void Screen_ShowString(SCREEN* Screen, u8 x,u8 y,u8 *chr,u8 size1)
{
    while((*chr>=' ')&&(*chr<='~'))//判断是不是非法字符!
	{
		Screen_ShowChar(Screen, x,y,*chr,size1);
		x+=size1/2;
		if(x>128-size1)  //换行
		{
			x=0;
			y+=2;
    	}
		chr++;
	}
}


void Screen_ShowBackString(SCREEN* Screen, u8 x,u8 y,u8 *chr,u8 size1)
{
    while((*chr>=' ')&&(*chr<='~'))//判断是不是非法字符!
	{
		Screen_ShowBackChar(Screen, x,y,*chr,size1);
		x+=size1/2;
		if(x>128-size1)  //换行
		{
			x=0;
			y+=2;
    	}
		chr++;
  	}
}


void Screen_ShowNum(SCREEN* Screen, u8 x,u8 y,u32 num,u8 len,u8 size1)
{
    u8 t,temp;
	u8 enshow=0;
	for(t=0;t<len;t++)
	{
		temp=(num/u8pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				Screen_ShowChar(Screen, x+8*t,y,' ',size1);
				continue;
			}else enshow=1; 
		 	 
		}
	 	Screen_ShowChar(Screen, x+8*t,y,temp+48,size1); 
	}
}


void Screen_ShowBackNum(SCREEN* Screen, u8 x,u8 y,u32 num,u8 len,u8 size1)
{
    u8 t,temp;
	u8 enshow=0;
	for(t=0;t<len;t++)
	{
		temp=(num/u8pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				Screen_ShowBackChar(Screen, x+8*t,y,' ',size1);
				continue;
			}else enshow=1; 
		 	 
		}
	 	Screen_ShowBackChar(Screen, x+8*t,y,temp+48,size1); 
	}
}



void Screen_ShowNum1(SCREEN* Screen, u16 x,u16 y,float num,u8 len,u8 size1)
{
    u8 t,temp;
	u8 flag=0;
	u32 num1;
	num1=num*100;
	len--;
	for(t=0;t<len;t++)
	{
		temp=(num1/u8pow(10,len-t-1))%10;
		if(temp!=0)flag++;
		if(t==(len-3))flag++;
		else if(t==(len-2))
		{
			Screen_ShowChar(Screen, x+8*(len-2),y,'.',size1);
			t++;
			len+=1;
		}
		if(flag == 0){Screen_ShowChar(Screen, x+8*t,y,' ',size1);}
	 	else{Screen_ShowChar(Screen, x+8*t,y,temp+48,size1);}
	}

}


void Screen_ShowBackNum1(SCREEN* Screen, u16 x,u16 y,float num,u8 len,u8 size1)
{
    u8 t,temp;
	u8 flag=0;
	u32 num1;
	num1=num*100;
	len--;
	for(t=0;t<len;t++)
	{
		temp=(num1/u8pow(10,len-t-1))%10;
		if(temp!=0)flag++;
		if(t==(len-3))flag++;
		else if(t==(len-2))
		{
			Screen_ShowBackChar(Screen, x+8*(len-2),y,'.',size1);
			t++;
			len+=1;
		}
		if(flag == 0){Screen_ShowBackChar(Screen, x+8*t,y,' ',size1);}
	 	else{Screen_ShowBackChar(Screen, x+8*t,y,temp+48,size1);}
	}    
}


void Screen_ShowInt(SCREEN* Screen, u8 x,u8 y,int num,u8 len,u8 size1)
{
    int numlen,sign=0;
	if(num<0)
	{
		sign=1;
		num=-num;
	}
	Screen_ShowNum(Screen, x,y,num,len,size1);
	if(sign)
	{
		numlen = Get_numlen(num);
		Screen_ShowChar(Screen, x+8*(len-numlen-1),y,'-',size1);
	}
}


void Screen_ShowBackInt(SCREEN* Screen, u8 x,u8 y,int num,u8 len,u8 size1)
{
    int numlen,sign=0;
	u8 t,temp;
	u8 enshow=0;
	if(num<0)
	{
		sign=1;
		num=-num;
	}
	for(t=0;t<len;t++)
	{
		temp=(num/u8pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				Screen_ShowBackChar(Screen, x+8*t,y,' ',size1);
				continue;
			}else enshow=1; 
		 	 
		}
	 	Screen_ShowBackChar(Screen, x+8*t,y,temp+48,size1); 
	}
	if(sign)
	{
		numlen = Get_numlen(num);
		Screen_ShowBackChar(Screen, x+8*(len-numlen-1),y,'-',size1);
	}
}



void Screen_ShowFloat(SCREEN* Screen, u16 x,u16 y,float num,u8 len,u8 size1)
{
    int numlen,sign=0;
	u8 length;
	length = len-2;
	if(num<0)
	{
		sign=1;
		num=-num;
		length--;
	}
	numlen = Get_numlen(num);
	length = length-numlen-1 ;
	Screen_ShowNum1(Screen, x,y,num,len,size1);
	if(sign)
	{
		Screen_ShowChar(Screen, x+8*length,y,'-',size1);
	}
}


void Screen_ShowBackFloat(SCREEN* Screen, u16 x,u16 y,float num,u8 len,u8 size1)
{
    int numlen,sign=0;
	u8 length;
	u8 t,temp,i;
	u8 flag=0;
	u32 num1;
	if(num<0)
	{
		sign=1;
		num=-num;
	}
	
	num1=num*100;
	numlen = Get_numlen(num1);
	if(numlen<3)
		numlen = 3;
	length = len-numlen-1-sign ;//去掉浮点和字符长度留给空格的大小
	
	for(t=0;t<length;t++)
	{
		Screen_ShowBackChar(Screen, x+8*t,y,' ',size1);
	}
	
	if(sign==1)
	{
		Screen_ShowBackChar(Screen, x+8*t,y,'-',size1);
		t++;
	}
	else
	{
		Screen_ShowBackChar(Screen, x+8*t,y,' ',size1);
	}
	for(i=0;i<numlen;t++,i++)
	{	
		if(i == numlen-2 && flag==0)
		{
			Screen_ShowBackChar(Screen, x+8*t,y,'.',size1);
			flag++;
			i--;
			continue;
		}
		temp=(num1/u8pow(10,numlen-i-1))%10;
		Screen_ShowBackChar(Screen, x+8*t,y,temp+48,size1);
	}
	
}



void Screen_ShowIntTag(SCREEN* Screen, u16 x,u16 y,int num,int len,u8 size1,u8 head)
{
	int numlen,sign=0;
	u8 t,temp;
	u8 enshow=0;
	head++;
	if(num<0)
	{
		sign=1;
		num=-num;
	}
	for(t=0;t<len;t++)
	{
		temp=(num/u8pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				Screen_ShowChar(Screen, x+8*t,y,' ',size1);
				continue;
			}else enshow=1; 
		 	 
		}
		if(t==(len-head))
		{
			Screen_ShowBackChar(Screen, x+8*t,y,temp+48,size1); 
			continue;
		}
	 	Screen_ShowChar(Screen, x+8*t,y,temp+48,size1); 
	}
	if(sign)
	{
		numlen = Get_numlen(num);
		Screen_ShowChar(Screen, x+8*(len-numlen-1),y,'-',size1);
	}
	

}


void Screen_ShowFloatTag(SCREEN* Screen, u16 x,u16 y,float num,int len,u8 size1,u8 head)
{
    int numlen,sign=0;
	u8 length;
	u8 t,temp,i;
	u8 flag=0;
	u32 num1;
	head++;
	if(num<0)
	{
		sign=1;
		num=-num;
	}
	
	num1=num*100;
	numlen = Get_numlen(num1);
	if(numlen<3)
		numlen = 3;
	length = len-numlen-1-sign ;//去掉浮点和字符长度留给空格的大小
	
	for(t=0;t<length;t++)
	{
		Screen_ShowChar(Screen, x+8*t,y,' ',size1);
	}
	
	if(sign==1)
	{
		Screen_ShowChar(Screen, x+8*t,y,'-',size1);
		t++;
	}
	else
	{
		Screen_ShowChar(Screen, x+8*t,y,' ',size1);
	}
	for(i=0;i<numlen;t++,i++)
	{	
		if(i == numlen-2 && flag==0)
		{
			Screen_ShowChar(Screen, x+8*t,y,'.',size1);
			flag++;
			i--;
			continue;
		}
		temp=(num1/u8pow(10,numlen-i-1))%10;
		if(i!=numlen-head)
		{
			Screen_ShowChar(Screen, x+8*t,y,temp+48,size1);
		}
		else
		{
			Screen_ShowBackChar(Screen, x+8*t,y,temp+48,size1);
		}

	}

}


